package org.hawk.gwt.ppc.reflect.lang;

import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.ParameterizedType;
import org.hawk.gwt.ppc.reflect.emul.java.lang.reflect.Type;

/**
 * ParameterizedType implementation for internal purposes.
 * Clients should never instantiate this class.
 * @author alex.bereznevatiy@gmail.com
 */
public class GWTParameterizedType implements ParameterizedType {
	
	private Class<?> raw;
	private Object[] params;
	
	public GWTParameterizedType(Object accessor, Class<?> raw, Object...params) {
		checkAccess(accessor);
		this.raw = raw;
		this.params = params;
	}

	static void checkAccess(Object accessor) {
		if (accessor == null || !accessor.getClass().getName().equals("org.hawk.gwt.ppc.reflect.lang.ClassDelegate$Accessor")) {
			throw new IllegalAccessError("This call is not permitted");
		}
	}

	public Type[] getActualTypeArguments() {
		Type[] result = new Type[params.length];
		for (int i = 0; i < params.length; i++) {
			if (params[i] instanceof Class) {
				result[i] = ClassDelegate.forClass((Class<?>)params[i]);
			} else {
				result[i] = (Type)params[i];
			}
		}
		return result;
	}

	public Type getRawType() {
		return ClassDelegate.forClass(raw);
	}

	public Type getOwnerType() {
		return null;
	}
	
	static String toString(Object type) {
		if (type instanceof Class) {
			return ((Class<?>)type).getName();
		}
		return type.toString();
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		result.append(((Class<?>)raw).getName());
		result.append('<');
		for (int i = 0; i < params.length; i++) {
			if (i > 0) {
				result.append(", ");
			}
			result.append(toString(params[i]));
		}
		result.append('>');
		return result.toString();
	}
}
